/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.anden.panningview;

import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorGroup;
import ohos.agp.components.Component;
import ohos.app.Context;

import java.util.ArrayList;

/**
 * BaseViewAnimator
 */
public abstract class BaseViewAnimator {
    private boolean mStarted = false;

    /**
     * DURATION
     */
    public static final long DURATION = 3000;
    private AnimatorGroup mAnimatorSet;
    private long mDuration = DURATION;
    private Context mContext;

    {
        mAnimatorSet = new AnimatorGroup();
    }

    /**
     * prepare
     *
     * @param target Component
     */
    protected abstract void prepare(Component target);

    /**
     * setTarget
     *
     * @param target Component
     * @return baseAnim
     */
    public BaseViewAnimator setTarget(Component target) {
        reset(target);
        prepare(target);
        mContext = target.getContext();
        return this;
    }

    /**
     * animate
     */
    public void animate() {
        start();
    }

    /**
     * restart
     */
    public void restart() {
        mStarted = false;
        mDuration = DURATION;
        start();
    }

    /**
     * reset the view to default status
     *
     * @param target Component
     */
    public void reset(Component target) {
        target.setAlpha(1);
        target.setScaleX(1);
        target.setScaleY(1);
        target.setTranslationX(0);
        target.setTranslationY(0);
        target.setRotation(0);
        if (mAnimatorSet != null) {
            mAnimatorSet.clear();
        }
    }

    /**
     * start to animate
     */
    public void start() {
        mAnimatorSet.setDuration(mDuration);
        if (mAnimatorSet.getRoundCount() > 0) {
            for (int ival = 0; ival < mAnimatorSet.getRoundCount(); ival++) {
                ArrayList<Animator> animators = mAnimatorSet.getAnimatorsAt(ival);
                for (int jval = 0; jval < animators.size(); jval++) {
                    if (animators.get(jval) instanceof PanningAnimatorValue) {
                        ((PanningAnimatorValue) animators.get(jval)).start();
                    }
                }
            }
        }
        mAnimatorSet.start();
        mStarted = true;
    }

    /**
     * setDuration to animate
     *
     * @param duration long
     * @return baseanim
     */
    public BaseViewAnimator setDuration(long duration) {
        mDuration = duration;
        return this;
    }

    /**
     * setStartDelay to animate
     *
     * @param delay long
     * @return baseview
     */
    public BaseViewAnimator setStartDelay(long delay) {
        getAnimatorAgent().setDelay(delay);
        return this;
    }

    /**
     * addAnimatorListener to animate
     *
     * @param listener Anim
     * @return baseanim
     */
    public BaseViewAnimator addAnimatorListener(Animator.StateChangedListener listener) {
        mAnimatorSet.setStateChangedListener(listener);
        return this;
    }

    /**
     * cancel to animate
     */
    public void cancel() {
        mAnimatorSet.cancel();
    }

    /**
     * clearAnim to animate
     */
    public void clearAnim() {
        mAnimatorSet.clear();
        mAnimatorSet.end();
    }

    /**
     * pauseAnim to animate
     */
    public void pauseAnim() {
        mAnimatorSet.pause();
    }

    /**
     * resumeAnim to animate
     */
    public void resumeAnim() {
        mAnimatorSet.resume();
    }

    /**
     * isRunning to animate
     *
     * @return true boolean
     */
    public boolean isRunning() {
        return mAnimatorSet.isRunning();
    }

    /**
     * isStarted to animate
     *
     * @return true boolean
     */
    public boolean isStarted() {
        return mStarted;
    }

    /**
     * removeAnimatorListener to animate
     *
     * @param listener Anim
     */
    public void removeAnimatorListener(Animator.StateChangedListener listener) {
        listener = null;
        mAnimatorSet.setStateChangedListener(listener);
    }

    /**
     * setCurveType to animate
     *
     * @param curveType integer
     * @return baseanim
     */
    public BaseViewAnimator setCurveType(int curveType) {
        mAnimatorSet.setCurveType(curveType);
        return this;
    }

    /**
     * getAnimatorAgent to animate
     *
     * @return baseanim
     */
    public AnimatorGroup getAnimatorAgent() {
        return mAnimatorSet;
    }
}
